/************************************************************************
 * The code is owned by mainframer.cn and Shang Tao
 * Without aproval of mainframer.cn and Shang Tao, remove the copyright
 * infomation is regarded invassion of proprietary copyright
 ***********************************************************************/
package com.mr.qa.action;

import java.util.Collection;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.hibernate.Transaction;

import com.mr.qa.GlobalConfigs;
import com.mr.qa.UserSession;
import com.mr.qa.UserSessionUtil;
import com.mr.qa.bo.MrIaskCategoryStatistics;
import com.mr.qa.bo.QuestionCategory;
import com.mr.qa.dao.impl.QuestionCategoryDAO;
import com.mr.qa.exception.QaException;
import com.mr.qa.form.QuestionCategoryForm;
import com.mr.qa.util.HibernateSessionFactory;


public class QuestionCategoryAction extends BaseAction {
        
	private static final Log log = LogFactory.getLog(QuestionCategoryAction.class);
	
	public ActionForward doAction(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception
        {

                String action = this.getAction(request);
                ActionMessages errors = this.getErrors(request);
                UserSession us = null;
                ActionForward af = null;                
                us = UserSessionUtil.getUserSession(request);
                //need verification 2008.2.21
                if(us == null)
                {
                    errors.add("relogin", new ActionMessage("login.required"));
                    action = "relogin";
                    af = mapping.findForward(action);
                }
                else if(!"1".equals(us.getType()))
                {
                    errors.add("noright", new ActionMessage("user.noright"));
                    action = "error";
                    af = mapping.findForward(action);
                }else if(!us.isAdminPasswordInput()){
                	StringBuffer uri = new StringBuffer(request.getRequestURI() + "?");
                	Enumeration paramNames = request.getParameterNames();
                	int i = 0;
                	while(paramNames.hasMoreElements()){
                		if(i != 0){
                			uri.append("&");
                		}
                		String name = (String)paramNames.nextElement();
                		uri.append(name + "=");
                		uri.append(request.getParameter(name));
                		i++;
                	}
                	
                	request.setAttribute("preURI",uri.toString());
                	action = "adminPass";
                	af = mapping.findForward(action);
                }
                if(af != null)return af;

                QuestionCategoryForm categoryForm = (QuestionCategoryForm)form;

                int page = categoryForm.getPage();
                if(page == 0)page = 1;
		if("list".equals(action))
                {
                        String id = categoryForm.getId();
                        Integer catId = null;
                        if(!(id == null || id.length() == 0))
                        {
                            catId = new Integer(id);
                        }
                        String from = request.getParameter("from");
                        if("delete".equals(from))
                        {
                            String parentId = categoryForm.getParentId();
                            if(parentId == null || parentId.length() == 0)
                                catId = null;
                            else
                            {
                                catId = new Integer(parentId); 
                            }
                        }
                        else if("add".equals(from))
                        {
                                String parentId = categoryForm.getParentId();
                                if(parentId == null || parentId.length() == 0)
                                    catId = null;
                                else
                                {
                                    catId = new Integer(parentId); 
                                }
                         }
                        Collection list;
                        if(catId == null)
                        {
                            list = list(null, categoryForm.getType());
                            request.setAttribute("cresultSize",list.size());
                        }
                        else
                        {
                                QuestionCategory qc = view(catId);
                                if(qc.getMrIaskCategory() != null)
                                {
                                    categoryForm.setParentId(""+qc.getMrIaskCategory().getId());
                                }    
                                request.setAttribute("pqcat",qc);
                                list = qc.getMrIaskCategories();
                                request.setAttribute("cresultSize",list.size());
                                request.setAttribute("resultSize",countQuestions(catId));
                                request.setAttribute("questions",getQuestions(page,catId));
                        }
                        request.setAttribute("qcats",list);
                        request.setAttribute("type", categoryForm.getType());
                }
                else if("predelete".equals(action))
                {
                    if(us == null)
                    {
                        errors.add("relogin", new ActionMessage("login.required"));
                        action = "relogin";
                    }
                    else if(!"1".equals(us.getType()))
                    {
                        errors.add("noright", new ActionMessage("user.noright"));
                        action = "error";
                    }
                    else
                    {
                        String id = categoryForm.getId();
                        if(id == null || id.length() == 0)
                            errors.add("",new ActionMessage("parameter.required","ID"));
                        else
                        {
                            int result = preDelete(new Integer(id));
                            QuestionCategory qc = this.view(new Integer(id));
                            if(result == 1)
                            {
                                errors.add("",new ActionMessage("questioncategory.predelete.childcategoryexist",qc.getName()));
                            }
                            else if(result == 2)
                            {
                                errors.add("",new ActionMessage("questioncategory.predelete.childquesitonexist",qc.getName()));
                            }
                        }
                        String hasError = "N";
                        if(errors.size() > 0)hasError = "Y";
                        request.setAttribute("hasError",hasError);
                    }
                    request.setAttribute("type", categoryForm.getType());
		}
                else if("premodify".equals(action))//will be discarded
                {
		    if(us == null)
		    {
		        errors.add("relogin", new ActionMessage("login.required"));
		        action = "relogin";
		    }
		    else if(!"1".equals(us.getType()))
		    {
		        errors.add("noright", new ActionMessage("user.noright"));
		        action = "error";
		    }
		    else
		    {
                        Integer id = new Integer(request.getParameter("id"));                
                        request.setAttribute("questions",getQuestions(page,id));
                        //get questions
                    }
		    request.setAttribute("type", categoryForm.getType());
		}
                else if("add".equals(action))
                {
		    if(us == null)
		    {
		        errors.add("relogin", new ActionMessage("login.required"));
		        action = "relogin";
		    }
		    else if(!"1".equals(us.getType()))
		    {
		        errors.add("noright", new ActionMessage("user.noright"));
		        action = "error";
		    }
		    else
		    {
                        /*
                        String name = categoryForm.getName();
                        String state = categoryForm.getState();
                        Integer priority = categoryForm.getPriority();
                        String parentId = categoryForm.getParentId();
                        String onlyForAdmin = categoryForm.getOnlyForAdmin();
                        boolean isAds = categoryForm.getIsAds();
                        String adContactMail = categoryForm.getAdCategoryContactMail();
                        Integer pId = null;
                        if(parentId != null && parentId.trim().length() > 0)
                        {
                            pId = new Integer(parentId);
                        }
                        if(state == null)state = "0";
                        */
                        add(categoryForm);
                    }
		}
                else if("modify".equals(action))
                {
		    if(us == null)
		    {
		        errors.add("relogin", new ActionMessage("login.required"));
		        action = "relogin";
		    }
		    else if(!"1".equals(us.getType()))
		    {
		        errors.add("noright", new ActionMessage("user.noright"));
		        action = "error";
		    }
		    else
		    {
                        String id = categoryForm.getId();
                        if(id == null || id.length() == 0)
                            errors.add("",new ActionMessage("parameter.required","ID"));
                        else
                        {
                            /*
                            String name = categoryForm.getName();
                            String state = categoryForm.getState();
                            Integer priority = categoryForm.getPriority();
                            String onlyForAdmin = categoryForm.getOnlyForAdmin();
                            boolean isAds = categoryForm.getIsAds();
                            if(state == null)state = "0";
                            String catId = categoryForm.getParentId();
                            Integer pId = null;
                            if(catId != null && catId.trim().length() > 0)
                            {
                                pId = new Integer(catId);
                            }
                            String adContactMail = categoryForm.getAdCategoryContactMail();
                            */
                            modify(categoryForm);
                        }
                    }
		    request.setAttribute("type", categoryForm.getType());
		}
                else if("delete".equals(action))
                {
		    if(us == null)
		    {
		        errors.add("relogin", new ActionMessage("login.required"));
		        action = "relogin";
		    }
		    else if(!"1".equals(us.getType()))
		    {
		        errors.add("noright", new ActionMessage("user.noright"));
		        action = "error";
		    }
		    else
		    {
                        String vcinSession = UserSessionUtil.getVerificationCodes(request);
                        String vc = categoryForm.getVc();
                        if(vc == null || vc.length() == 0)
                        {
                            errors.add("",new ActionMessage("verificationcode.required"));
                        }
                        else
                        {
                            if(vc.equals(vcinSession))
                            {
                                String id = categoryForm.getId();
                                if(id == null || id.length() == 0)
                                    errors.add("",new ActionMessage("parameter.required","ID"));
                                else
                                {
                                    String parentId = delete(new Integer(id));
                                    if(parentId == null)parentId = "";
                                    categoryForm.setId(parentId);//applicable?
                                }
                            }
                            else
                            {
                                errors.add("",new ActionMessage("verificationcode.error","ID"));
                            }
                        }
                        if(errors.size() > 0)
                        action = "predelete";
                    }
		}
                else if("preadd".equals(action)){
                	request.setAttribute("type", categoryForm.getType());
                }
	    if(errors.size() > 0)           
	        saveErrors(request, errors);
	    af = mapping.findForward(action);
            return af;
	}
	
        private int countQuestions(Integer catId) throws QaException
        {
            Transaction tx = null;
            int count = 0; 
            try
            {
                QuestionCategoryDAO categoryDAO = new QuestionCategoryDAO();
                tx = HibernateSessionFactory.getSession().beginTransaction();
                count = categoryDAO.countQuestions(catId);
                tx.commit();
            }
            catch(Exception e)
            {
                if(tx != null)tx.rollback();
                throw new QaException(e);
            }
            finally
            {
                HibernateSessionFactory.closeSession();  
            }
            return count;
        }

        private Collection getQuestions(int page,Integer catId) throws QaException
        {
            Transaction tx = null;
            Collection list = null;
            try
            {
                QuestionCategoryDAO categoryDAO = new QuestionCategoryDAO();
                categoryDAO.setPage(page,15);
                tx = HibernateSessionFactory.getSession().beginTransaction();
                list = categoryDAO.findQuestions(catId);
                tx.commit();
                return list;
            }
            catch(Exception e)
            {
                if(tx != null)tx.rollback();
                throw new QaException(e);
            }
            finally
            {
                HibernateSessionFactory.closeSession();  
            }
        
        }
        
        
        private int preDelete(Integer catId) throws QaException
        {
            Transaction tx = null;
            int result = 0;
            try
            {
                QuestionCategoryDAO categoryDAO = new QuestionCategoryDAO();
                tx = HibernateSessionFactory.getSession().beginTransaction();
                QuestionCategory category = categoryDAO.findById(catId);
                if(category.getMrIaskCategories().size() > 0)
                    result = 1;
                else if(category.getMrIaskQuestions().size() >0)
                    result = 2;
                tx.commit();                
            }
            catch(Exception e)
            {
                if(tx != null)tx.rollback();
                throw new QaException(e);
            }
            finally
            {
                HibernateSessionFactory.closeSession();  
            }
            return result;
        }
	
	private Collection list(Integer pid, Integer categoryType) throws QaException
        {
	    Transaction tx = null;
	    Collection list = null;
	    try
	    {
		QuestionCategoryDAO categoryDAO = new QuestionCategoryDAO();
	        tx = HibernateSessionFactory.getSession().beginTransaction();
		if(pid == null || pid.intValue() == 0){
			list = categoryDAO.findByType(categoryType);
		}else{
			QuestionCategory category = categoryDAO.findById(pid);
			list = category.getMrIaskCategories();
		}
	        tx.commit();
                return list;
	    }
	    catch(Exception e)
	    {
	        if(tx != null)tx.rollback();
	        throw new QaException(e);
	    }
	    finally
	    {
	        HibernateSessionFactory.closeSession();  
	    }
                
	}
	public QuestionCategory view(Integer id) throws QaException
        {
	    Transaction tx = null;
	    try
	    {
		QuestionCategoryDAO categoryDAO = new QuestionCategoryDAO();
	        tx = HibernateSessionFactory.getSession().beginTransaction();
		QuestionCategory category = categoryDAO.findById(id);
	        tx.commit();                
		return category;
	    }
	    catch(Exception e)
	    {
                if(tx != null)tx.rollback();
                throw new QaException(e);
	    }
	    finally
	    {
                HibernateSessionFactory.closeSession();  
	    }
	}
	//String name, String state, Integer priority,
//         String onlyForAdmin,boolean isAds,String adContactMail,Integer pid
	public void add(QuestionCategoryForm form) throws QaException
        {
            Transaction tx = null;
            try
            {
                String parentId = form.getParentId();
                Integer pid = (parentId == null || parentId.trim().length() == 0)?null:new Integer(parentId);
                QuestionCategoryDAO categoryDAO = new QuestionCategoryDAO();
                QuestionCategory parent = null;
                tx = HibernateSessionFactory.getSession().beginTransaction();
                if(pid != null && pid.intValue() > 0)
                {
                    parent = categoryDAO.findById(pid);
                }
                QuestionCategory category = new QuestionCategory();
                String name = form.getName();
                category.setName(name);
                String state = form.getState();
                if(state == null)state = "0";
                category.setState(state);
                if(parent != null)
                {
                    category.setLevel(parent.getLevel()+1);                        
                    category.setMrIaskCategory(parent);
                }
                else
                {
                    category.setLevel(1);
                }
                Integer priority = form.getPriority();
                category.setPriority(priority);
                String onlyForAdmin = form.getOnlyForAdmin();
                category.setOnlyForAdmin(onlyForAdmin);
                boolean isAds = form.getIsAds();
                category.setIsAds(isAds);
                boolean isTraining = form.getIsTraining();
                //2008.12.18
                category.setIsTraining(isTraining);
                String adContactMail = form.getAdCategoryContactMail();
                category.setAdCategoryContactMail(adContactMail);
                MrIaskCategoryStatistics mics = new MrIaskCategoryStatistics();
                mics.setTotal(new Integer(0));
                mics.setCategoryType("Q");
                mics.setMrIaskCategory(category);
                category.setMrIaskCategoryStatistics(mics);
                //the parent ad attribute is set to true forcibly 2008-8-27
                if(isAds && parent != null && !parent.getIsAds())
                {
                    parent.setIsAds(isAds);
                    categoryDAO.update(parent);
                }
                if(isTraining && parent != null && !parent.getIsTraining())
                {
                    parent.setIsTraining(isTraining);
                    categoryDAO.update(parent);
                }
                category.setType(form.getType());
                categoryDAO.save(category);
                tx.commit();
            }
	    catch(Exception e)
	    {
	        if(tx != null)tx.rollback();
	        throw new QaException(e);
	    }
	    finally
	    {
	        HibernateSessionFactory.closeSession();  
	    }
            //to inform taglib to refresh category structure
            GlobalConfigs.CATEGORYCHANGED = true;
	}
	
        
	//QuestionCategoryForm form
        
        //Integer id, String name, String state, Integer priority
        //         ,String onlyForAdmin,boolean isAds,String adContactMail
	public boolean modify(QuestionCategoryForm form) throws QaException
        {
            boolean result = true;
            Transaction tx = null;
            try
            {
                QuestionCategoryDAO categoryDAO = new QuestionCategoryDAO();
                tx = HibernateSessionFactory.getSession().beginTransaction();
                Integer id = new Integer(form.getId());
                QuestionCategory category = categoryDAO.findById(id);
                MrIaskCategoryStatistics mics = category.getMrIaskCategoryStatistics();
                if(mics == null)
                {
                    mics = new MrIaskCategoryStatistics();
                    mics.setCategoryType("Q");
                    mics.setTotal(new Integer(category.getMrIaskQuestions().size()));
                    mics.setMrIaskCategory(category);
                    category.setMrIaskCategoryStatistics(mics);
                }
                String name = form.getName();
                category.setName(name);
                String state = form.getState();
                if(state == null)state = "0";
                category.setState(state);
                Integer priority = form.getPriority();
                category.setPriority(priority);
                String onlyForAdmin = form.getOnlyForAdmin();
                category.setOnlyForAdmin(onlyForAdmin);
                boolean isAds = form.getIsAds();
                category.setIsAds(isAds);
                boolean isTraining = form.getIsTraining();
                category.setIsTraining(isTraining);
                String adContactMail = form.getAdCategoryContactMail();
                category.setAdCategoryContactMail(adContactMail);
                //the parent ad attribute is set to true forcibly 2008-8-27
                if(isAds)
                {
                    QuestionCategory parent = category.getMrIaskCategory();
                    if(parent != null && !parent.getIsAds())
                    {
                        parent.setIsAds(isAds);
                        categoryDAO.update(parent);
                    }
                }
                else if(isTraining) {
                    QuestionCategory parent = category.getMrIaskCategory();
                    if(parent != null && !parent.getIsTraining())
                    {
                        parent.setIsTraining(isTraining);
                        categoryDAO.update(parent);
                    }
                }
                category.setIsLock(form.getIsLock());
                categoryDAO.update(category);
                tx.commit();
            }
	    catch(Exception e)
	    {
	        if(tx != null)tx.rollback();
	        throw new QaException(e);
	    }
	    finally
	    {
	        HibernateSessionFactory.closeSession();  
	    }
	    //to inform taglib to refresh category structure
	    GlobalConfigs.CATEGORYCHANGED = true;
            return result;
	}
	
        /**
         * return the parentId
         */
	public String delete(Integer id) throws QaException
        {
            Transaction tx = null;
            try
            {
                QuestionCategoryDAO categoryDAO = new QuestionCategoryDAO();                
                tx = HibernateSessionFactory.getSession().beginTransaction();
                QuestionCategory category = categoryDAO.findById(id);
                String parentCatId = null;
                if(category.getMrIaskCategory() != null)
                    parentCatId = category.getMrIaskCategory().getId()+"";
                categoryDAO.delete(category);
                tx.commit();
                //to inform taglib to refresh category structure
                GlobalConfigs.CATEGORYCHANGED = true;
                return parentCatId;
            }
	    catch(Exception e)
	    {
	        if(tx != null)tx.rollback();
	        throw new QaException(e);
	    }
	    finally
	    {
	        HibernateSessionFactory.closeSession();  
	    }
	}
}
